/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#include "stdafx.h"
#include "编译声明代码.h"
#include <core/设备内存缓存.h>
#include <文件/file_文件名数据.h>

#include <字符串数值互换.h>
#include "节点数据声明.h"



static std::vector<E_JIT_FunParam>  g函数指针;

typedef void* (*ptr_JIT_Fun_vec3_alloc变量)(uint64 num);
typedef void(*ptr_JIT_Fun_vec3_resize变量)(void* val, uint64 num);

static std::map<std::string, std::string[2]> g内联函数代码;
static bool g内联函数代码改变 = true;



std::vector<std::string> S_JIT_函数指针名称::g函数指针名称 = {
	//"f_JIT_Fun_vec3_alloc变量",
	//"f_JIT_Fun_vec3_resize变量",
};

std::vector<std::string> S_JIT_函数指针名称::g返回类型 = {
	//"void*",
	//"void",
};

std::vector<std::string> S_JIT_函数指针名称::g参数类型 = {
	//"uint64 num",
	//"void* val, uint64 num",
};


std::string f_代码构建_函数指针() {
	static std::string code;
	if (code.size()) {
		return code;
	}
	
	uint32 num = S_JIT_函数指针名称::g函数指针名称.size();
	for (uint32 i = 0; i < num; ++i) {
		code += "typedef "+ S_JIT_函数指针名称::g返回类型[i] +"(*ptr_" + S_JIT_函数指针名称::g函数指针名称[i] + ")(" + S_JIT_函数指针名称::g参数类型[i] + ");\n";
		code += "static ptr_" + S_JIT_函数指针名称::g函数指针名称[i] + " " + S_JIT_函数指针名称::g函数指针名称[i] + ";\n";
	}

	return code;
}


std::vector<E_JIT_FunParam>& f_代码构建_取参数函数指针() {
	return g函数指针;
}

std::string f_代码构建_JIT函数指针初始化() {
	static std::string code;
	if (code.size()) return code;

	code += "extern \"C\" { __declspec(dllexport)  void f_fnPtr_init( E_JIT_FunParam* 参数); }\n";
	code += "void f_fnPtr_init(E_JIT_FunParam* 参数){\n";
	//code += "for(uint32 i=0; i<参数数量; ++i){\n";
	for (uint32 i = 0; i < S_JIT_函数指针名称::g函数指针名称.size(); ++i) {
		code += S_JIT_函数指针名称::g函数指针名称[i] + " = (ptr_" + S_JIT_函数指针名称::g函数指针名称[i] + ")(参数["+ f_整数值转字符串(i) + "].m_data); \n";
	}
	//code += "}\n";
	code += "}\n";

	return code;
}

void f_代码构建_添加JIT初始化函数指针(std::string 定义名称,  std::string 返回类型, std::string 参数类型, void* fp) {
	//S_JIT_函数指针名称::g函数指针类型定义名称.push_back(定义名称);
	S_JIT_函数指针名称::g函数指针名称.push_back(定义名称);
	S_JIT_函数指针名称::g返回类型.push_back(返回类型);
	S_JIT_函数指针名称::g参数类型.push_back(参数类型);

	E_JIT_FunParam e{};
	e.m_data = fp;
	g函数指针.push_back(e);
}

std::string f_代码构建_预定义类型() {
	static std::string code;
	if (code.size()) return code;
	
	code += "struct S_边;\n";
	code += "struct S_面;\n";
	code += "struct S_Mesh;\n";
	code += "struct S_多边形;\n";
	code += "struct S_曲线;\n";
	//code += "struct S_多边形面;\n";
	code += "struct S_物体;\n";
	code += "struct S_纹理;\n";
	
	code += DEF_S(struct C_节点基类)";\n";
	code += DEF_S(struct C_插座基类)";\n";
	//code += "struct S_多边形元素;\n";
	
	code += "#define DEF_Max(a,b) (((a) > (b)) ? (a) : (b))\n";
	code += "#define DEF_Min(a,b) (((a) < (b)) ? (a) : (b))\n";

	code += DEF_S(_S_Array);
	code += "\n";
	code += DEF_S(_S_边Array);
	code += "\n";
	code += DEF_S(_S_MaterialArray);
	code += "\n";
	code += DEF_S(_S_1DArray);
	code += "\n";
	

	return code;
}

std::string f_代码构建_创建vec3数组(std::string name) {
	std::string code;
	code = "void* " + name + " = " + DEF_S(f_JIT_Fun_vec3_alloc) + "(false, 0, 0, {}, {}, {});\n";
	return code;
}

std::string f_代码构建_取vec3数组数量(std::string& 变量名称, std::string var) {
	变量名称 += "_vec3数组数量";
	std::string code = "uint32 " + 变量名称 + " = ";
	code = DEF_S(f_JIT_Fun_vec3_size);
	code += "(" + var + ")";
	return code;
}

std::string f_代码构建_vec3数组分配(std::string name, std::string num) {
	std::string 分配代码;
	分配代码 += "void* " + name + " = " + DEF_S(f_JIT_Fun_vec3_alloc) + "(false, " + num + ", 0, {}, {}, {});\n";
	return 分配代码;
}

std::string f_代码构建_释放vec3数组(const std::string& name) {
	std::string 释放 = DEF_S(f_JIT_Fun_vec3_free);
	释放 += "(" + name + ");\n";
	return 释放;
}

std::string f_代码构建_新建变量忽略负数(const std::string& 变量, std::string& 新变量名称) {
	std::string code;
	新变量名称 += "变量忽略负数";
	code = "uint32 " + 新变量名称 + " = " + 变量 + " < 0 ? " + "0 : " + 变量 + ";\n";
	return code;
}

std::string f_代码构建_多边形边数组数量(std::string& 变量名称, const std::string& 多边形代码) {
	变量名称 += "_多边形边数组数量";
	std::string code = "uint32 " + 变量名称 + " = ";
	code += DEF_S(f_多边形_边数量);
	code += "(" + 多边形代码 + ");\n";
	return code;
}



std::string f_代码构建_创建vec3_Array(std::string& 新变量名称, const std::string& 数量) {
	std::string code = "S_Vec3Array* " + 新变量名称 + " = " + DEF_S(f_vec3_array_alloc) + "(" + 数量 + ");\n";
	return code;
}

static std::map<uint32, std::string> DBUGE_记录申请;
static std::map<uint32, std::string> DBUGE_记录释放;
static std::mutex 记录锁;

std::string f_代码构建_创建Array(E_值类型 类型, const std::string& 数量) {
	//记录锁.lock();
	//static uint32 计数 = 0;
	//DBUGE_记录申请[计数] = ++计数;
	//记录锁.unlock();

	switch (类型) {
		case E_值类型::e_Type_Bool_1D:
			return DEF_S((S_BoolArray*)f_core_array_new)"(" + 数量 + ", sizeof(" + DEF_S(bool) + "), false);\n";
		case E_值类型::e_Type_I8_1D:
			return DEF_S((S_I8Array*)f_core_array_new)"(" + 数量 + ", sizeof(" + DEF_S(int8) + "), false);\n";
		case E_值类型::e_Type_F32_1D:
			return DEF_S((S_F32Array*)f_core_array_new)"(" + 数量 + ", sizeof(" + DEF_S(float32) + "), false);\n";
		case E_值类型::e_Type_I32_1D:
			return DEF_S((S_I32Array*)f_core_array_new)"(" + 数量 + ", sizeof(" + DEF_S(int32) + "), false);\n";

		case E_值类型::e_Type_UI32_1D:
			return DEF_S((S_UI32Array*)f_core_array_new)"(" + 数量 + ", sizeof(" + DEF_S(uint32) + "), false);\n";
		case E_值类型::e_Type_UI32_2D:
			return DEF_S((S_UI32Array2D*)f_core_array_new)"(" + 数量 + ", sizeof(" + DEF_S(S_UI32Array*) + "), true);\n";

		case E_值类型::e_Type_Vec2_1D:
			return DEF_S((S_Vec2Array*)f_core_array_new)"(" + 数量 + ", sizeof(" + DEF_S(vec2) + "), false);\n";
		case E_值类型::e_Type_uVec2_1D:
			return DEF_S((S_uVec2Array*)f_core_array_new)"(" + 数量 + ", sizeof(" + DEF_S(uvec2) + "), false);\n";
		case E_值类型::e_Type_Vec3_1D:
			return DEF_S((S_Vec3Array*)f_core_array_new)"(" + 数量 + ", sizeof(" + DEF_S(vec3) + "), false);\n";
		case E_值类型::e_Type_iVec2_1D:
			return DEF_S((S_iVec2Array*)f_core_array_new)"(" + 数量 + ", sizeof(" + DEF_S(ivec2) + "), false);\n";
		case E_值类型::e_Type_iVec3_1D:
			return DEF_S((S_iVec3Array*)f_core_array_new)"(" + 数量 + ", sizeof(" + DEF_S(ivec3) + "), false);\n";

		case E_值类型::e_Type_iVec3_2D:
			return DEF_S((S_iVec3Array2D*)f_core_array_new)"(" + 数量 + ", sizeof(" + DEF_S(S_iVec3Array*) + "), true);\n";
		case E_值类型::e_Type_Vec3_2D:
			return DEF_S((S_Vec3Array2D*)f_core_array_new)"(" + 数量 + ", sizeof(" + DEF_S(S_Vec3Array*) + "), true);\n";

		case E_值类型::e_Type_Vec4_1D:
			return DEF_S((S_Vec4Array*)f_core_array_new)"(" + 数量 + ", sizeof(" + DEF_S(vec4) + "), false);\n";
		case E_值类型::e_Type_Mat4X4_1D:
			return "(S_Mat44Array*)f_core_array_new(" + 数量 + ", sizeof(Mat44f), false);\n";

		case E_值类型::e_Type_多边形边1D:
			return DEF_S((S_边Array*)f_core_array_new)"(" + 数量 + ", sizeof(" + DEF_S(S_边*) + "), false);\n";
		case E_值类型::e_Type_多边形_1D:
			return DEF_S((S_多边形Array*)f_core_array_new)"(" + 数量 + ", sizeof(" + DEF_S(S_多边形*) + "), false);\n";

		case E_值类型::e_Type_多边形元素:
			return DEF_S((S_多边形元素*)f_core_array_new)"(" + 数量 + ", sizeof(" + DEF_S(S_面*) + "), false);\n";
		case E_值类型::e_Type_多边形元素1D:
			return DEF_S((S_多边形元素Array*)f_core_array_new)"(" + 数量 + ", sizeof(" + DEF_S(S_多边形元素*) + "), false);\n";

		case E_值类型::e_Type_Array:
			return DEF_S(S_Array*)"f_core_array_new(" + 数量 + ", sizeof(uint8), false);\n";
	}
	//DEF_S(sizeof(S_iVec3Array*));

	return "";
}

std::string f_代码构建_销毁数组(std::string 新变量名称) {
	std::string code = "f_core_array_free((S_Array*)" + 新变量名称 + ");\n";

	//记录锁.lock();
	//static uint32 计数 = 0;
	//DBUGE_记录释放[计数] = ++计数;
	//记录锁.unlock();

	return code;
}

std::string f_代码构建_Array数组数量(std::string var) {
	return "(" + var + "->count)";
}

std::string f_代码构建_Array元素大小(std::string var) {
	return DEF_S(f_core_array_get_elt_size)"((S_Array*)" + var + ")";
}

bool f_代码构建_是否为单值浮点(E_值类型 type) {
	switch (type) {
		case E_值类型::e_Type_F32:
		case E_值类型::e_Type_F64:
		case E_值类型::e_Type_F32_1D:
		case E_值类型::e_Type_F64_1D:
			return true;
	}
	return false;
}

bool f_代码构建_是否为单值数组浮点(E_值类型 type) {
	switch (type) {
		//case E_值类型::e_Type_F32:
		//case E_值类型::e_Type_F64:
		case E_值类型::e_Type_F32_1D:
		case E_值类型::e_Type_F64_1D:
			return true;
	}
	return false;
}

bool f_代码构建_是否为矢量浮点(E_值类型 type) {
	switch (type) {
		case E_值类型::e_Type_Vec2:
		case E_值类型::e_Type_Vec3:
		case E_值类型::e_Type_Vec4:
			return true;
	}
	return false;
}

bool f_代码构建_是否为矢量数组浮点(E_值类型 type) {
	switch (type) {
		case E_值类型::e_Type_Vec2_1D:
		case E_值类型::e_Type_Vec3_1D:
		case E_值类型::e_Type_Vec4_1D:
			return true;
	}
	return false;
}

E_值类型 f_代码构建_多维数组元素(E_值类型 type) {
	switch (type) {
		case E_值类型::e_Type_UI32_2D: return E_值类型::e_Type_UI32_1D;

		case E_值类型::e_Type_Vec3_2D: return E_值类型::e_Type_Vec3_1D;
		case E_值类型::e_Type_iVec3_2D: return E_值类型::e_Type_iVec3_1D;
	}
	return E_值类型::e_Type_None;
}

E_值类型 f_代码构建_多维数组(E_值类型 type) {
	switch (type) {
		case E_值类型::e_Type_UI32_2D: return E_值类型::e_Type_UI32_1D;

		case E_值类型::e_Type_Vec3_2D: return E_值类型::e_Type_Vec3_1D;
		case E_值类型::e_Type_iVec3_2D: return E_值类型::e_Type_iVec3_1D;
	}
	return E_值类型::e_Type_None;
}

std::string f_代码构建_i32GPU变量(S_Props& 属性) {
	std::string code = "i32_GParam.i32Ptr[";
	code += f_整数值转字符串(属性.m_GPU缓存[0].m_Mem.m_偏移);
	code += "]";
	return code;
}

void f_代码构建_内联函数声明定义(const std::string keyName, const std::string& 函数声明, const std::string& 函数代码) {
	g内联函数代码[keyName][0] = 函数声明;
	g内联函数代码[keyName][1] = 函数代码;
	g内联函数代码改变 = true;
}

bool f_代码构建_内联函数保存到文件() {
	std::string path = S_节点数据::g_工程文件节点代码路径 + "Inline_fun.h";

	if (g内联函数代码改变 || f_file_文件是否存在(path) == false) {
		std::string hpp;

		
		FILE* f = fopen(path.c_str(), "w");
		if (f) {
			hpp += "#pragma once \n";
			hpp += "extern ";
			hpp += DEF_S(DEF_编译全局可调参数)";\n";

			for (auto k : g内联函数代码) {
				hpp += k.second[0];
			}
			for (auto k : g内联函数代码) {
				hpp += k.second[1];
			}

			f_file_保存文本(f, hpp);
			fclose(f);
		}
	}

	g内联函数代码改变 = false;
	return g内联函数代码.size();
}

void f_代码构建_清除代码缓存() {
	g内联函数代码.clear();
	g内联函数代码改变 = true;
}








